package com.lovely3x.jobservice.executors;

import android.support.annotation.MainThread;
import android.support.annotation.NonNull;
import android.support.annotation.WorkerThread;

import com.lovely3x.jobservice.JobService;
import com.lovely3x.jobservice.serializer.TaskSerializer;
import com.lovely3x.jobservice.task.Progress;
import com.lovely3x.jobservice.task.Task;

/**
 * 任务执行者
 * Created by lovely3x on 16-1-26.
 */
public interface TaskExecutor {
    /**
     * 是否开启DEBUG
     */
    boolean DEBUG = JobService.DEBUG;

    /**
     * 执行任务
     * 在任务的执行过程中，你可以需要偶进度控制
     * 在系统想要查看进度时能够随时提供当前的任务的进度
     *
     * @param task 需要执行的任务
     * @return 执行的结果 如果异常为null则表示执行成功
     */
    @WorkerThread
    Exception execute(Task task);

    /**
     * 移除任务
     */
    @MainThread
    boolean remove();

    /**
     * 暂停
     */
    @MainThread
    Exception stop();

    /**
     * 恢复暂停的任务
     *
     * @param task
     * @param progress
     */
    @MainThread
    Exception resume(Task task, Progress progress);

    /**
     * 是否能够处理这个任务
     * 如果当前的这个处理器能够处理这个任务对象
     * 那么这个任务就会被交给当前的这个处理器
     *
     * @param task 需要判断的任务
     * @return true or false
     */
    @MainThread
    boolean handleable(Task task);

    /**
     * 获取当前的任务执行进度
     *
     * @return 当前的进度
     */
    @NonNull
    Progress getProgress();

    /**
     * 服务启动后会依次启动这些执行者
     * 执行这个方法就说明执行者被创建了，你可以在这里读取一些任务信息
     *
     * @param jobService 工作服务
     */
    void onCreate(@NonNull JobService jobService);

    /**
     * 当工作服务执行完成或者是即将销毁
     * 将会执行这个方法，你可以在这里执行扫尾工作
     */
    void onDestroy();

    /**
     * 是否已经初始化，一般情况下我们认为没有执行{@link #onCreate(JobService)}
     * 或已经执行{@link #onDestroy()} 方法则说明尚未初始化
     *
     * @return true or false
     */
    boolean isInitialized();

    /**
     * 是否已经销毁
     * 如果已经销毁 则无法执行除{@link #recycle()}方法以外的操作了
     * 该类可能稍后会被回收
     *
     * @return true or false
     */
    boolean isDestroyed();

    /**
     * 回收该类,如果可以回收,则可能即将被复用
     *
     * @return true or false
     */
    boolean recycle();

    /**
     * 序列化
     * 将当前的任务状态进行序列化
     * 事实上,序列化和反序列化都应该是有提供的序列化器实现
     * 而在这里没有提供反序列化接口,因为在服务启动时是不会存在任务执行器的,仅仅存在序列化工厂
     * 所以反序列化是由序列化工厂实现的
     *
     * @param serializer 序列化器
     */
    @WorkerThread
    void serialize(TaskSerializer serializer);

    abstract class AbstractTaskExecutor implements TaskExecutor {
        /**
         * 是否开启DEBUG
         */
        public static final boolean DEBUG = JobService.DEBUG;
        public final String TAG = this.getClass().getSimpleName();
        protected JobService mJobService;

        /**
         * 服务启动后会依次启动这些执行者
         * 执行这个方法就说明执行者被创建了，你可以在这里读取一些任务信息
         *
         * @param jobService 工作服务
         */
        @MainThread
        public void onCreate(@NonNull JobService jobService) {
            this.mJobService = jobService;
        }

        /**
         * 当工作服务执行完成或者是即将销毁
         * 将会执行这个方法，你可以在这里执行扫尾工作
         */
        @MainThread
        public void onDestroy() {
            mJobService = null;
        }

        /**
         * 是否已经初始化，一般情况下我们认为没有执行{@link #onCreate(JobService)}
         * 或已经执行{@link #onDestroy()} 方法则说明尚未初始化
         *
         * @return true or false
         */
        public boolean isInitialized() {
            return mJobService != null;
        }

        @Override
        public boolean isDestroyed() {
            return mJobService == null;
        }

        @Override
        public boolean recycle() {
            return false;
        }

    }

}
